using System;
using System.Reflection;

namespace Ioc.Kernel
{
    public class Constructor : IComparable
    {
        private readonly ConstructorInfo constructor;
        private Type[] signature;

        public ConstructorInfo GetConstructor
        {
            get { return constructor; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Constructor"/> class.
        /// </summary>
        /// <param name="constructor">The constructor.</param>
        public Constructor(ConstructorInfo constructor)
        {
            this.constructor = constructor;
            signature = null;
        }

        /// <summary>
        /// Generates the signature.
        /// </summary>
        /// <returns></returns>
        public Type[] GenerateSignature()
        {
            if (signature == null)
            {
                var parameters = constructor.GetParameters();
                signature = new Type[parameters.Length];

                for (int i = 0; i < parameters.Length; ++i)
                {
                    signature.SetValue(parameters[i].ParameterType, i);
                }
            }
            return signature;
        }

        /// <summary>
        /// Compares the current instance with another object of the same type.
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>
        /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than <paramref name="obj"/>. Zero This instance is equal to <paramref name="obj"/>. Greater than zero This instance is greater than <paramref name="obj"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// 	<paramref name="obj"/> is not the same type as this instance. </exception>
        public int CompareTo(object obj)
        {
            var objToCompare = obj as Constructor;
            // Descending sort
            return -1 *(constructor.GetParameters().Length.CompareTo(objToCompare.GetConstructor.GetParameters().Length));
        }
    }
}